package com.kele.gateway.filter;


import com.alibaba.fastjson.JSON;
import com.kele.gateway.remote.AuthServiceRemote;
import com.kele.gateway.utils.RedisUtil;
import com.kele.utils.RequestResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * @author chunhui.li
 * @date 2022/9/17 21:56
 * @Description 自定义全局token校验
 * @ClassName GlobalTonkenFilter
 */
@Component
public class GlobalTonkenFilter implements GlobalFilter, Ordered {

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    AuthServiceRemote authServiceRemote;


    private static final String PATH_LOGIN = "/login/getAuth";
    private static final String PATH_REGISTER = "/login/register";
//    public static final String TOKEN_REDIS_KEY = "Authorization:token:";
    public static final String TOKEN_KEY = "Authorization";


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();
        /**
         * 获得请求路径
         */
        String path = request.getPath().toString();
        //登录请求直接到认证服务
        if (path.contains(PATH_LOGIN) || path.contains(PATH_REGISTER)) {
            return chain.filter(exchange);
        }

        //验证token
        HttpHeaders headers = request.getHeaders();
        List<String> headerList = headers.get(TOKEN_KEY);
        if (headerList == null) {
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.BAD_REQUEST);
            response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
            String msg = "token参数缺失";
            DataBuffer wrap = response.bufferFactory().wrap(JSON.toJSONString(RequestResultUtil.error(400, msg)).getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(wrap));
        }
        String token = headerList.get(0);
        if (!authServiceRemote.checkToken(token)) {
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
            String msg = "登陆已过期，请重新登陆";
            DataBuffer wrap = response.bufferFactory().wrap(JSON.toJSONString(RequestResultUtil.error(401, msg)).getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(wrap));
        }
        ServerHttpRequest host = request.mutate().header("token", token).build();
        ServerWebExchange build = exchange.mutate().request(host).build();
        return chain.filter(build);
    }


    /**
     * 实现Ordered接口保证优先级，值越小加载的优先级越高
     *
     * @return
     */
    @Override
    public int getOrder() {
        return -1;
    }
}
